package edu.um.variable;

import edu.um.token.TokenKind;

public enum VariableType {
  WORD {

    @Override
    public boolean isNumeric() {
      return true;
    }

    @Override
    public boolean admits(Object value) {
      return (TokenKind.CONST_WORD.accepts(value.toString())
          || TokenKind.CONST_BYTE.accepts(value.toString()));
    }
  },
  BYTE {
    @Override
    public boolean isNumeric() {
      return true;
    }

    @Override
    public boolean admits(Object value) {
      return (TokenKind.CONST_BYTE.accepts(value.toString()));
    }
  },
  STRING_BLANCO {
    @Override
    public boolean admits(Object value) {
      return (TokenKind.STRING_BLANCO.accepts(value.toString()));
    }
  },
  STRING_SUBRAYADO{
    @Override
    public boolean admits(Object value) {
      return (TokenKind.STRING_SUBRAYADO.accepts(value.toString()));
    }
  },
  ARRAY {
    private VariableType type;

    @Override
    public void specifyType(VariableType theType) {
      if (type == VariableType.ARRAY || type == VariableType.REGISTRO) {
        throw new IllegalArgumentException(
            "No es posible crear un array de array o registro");
      }
      type = theType;
    }
  },
  REGISTRO;

  public void specifyType(VariableType type) {
    throw new IllegalArgumentException(
        "Solamente los arrays pueden especicar tipo de variable");

  }

  public static VariableType createArrayType(String theName,
      VariableType theType) {
    VariableType type = VariableType.ARRAY;

    type.specifyType(theType);
    return type;
  }

  public final boolean admitsValue(Object value) {
    if (value == null) {
      return true;
    }
    return admits(value);
  }

  protected boolean admits(Object value) {
    return false;
  }

  public boolean isNumeric() {
    return false;
  }
}
